package org.zoomdev.zoom.rpc.server;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.zoomdev.zoom.async.annotation.Async;
import org.zoomdev.zoom.async.impl.Asyncs;

public class ServerHandle extends ChannelInboundHandlerAdapter {

    private static final Log log = LogFactory.getLog(ServerHandle.class);
    private final ServiceInvoker invoker;
    
    public ServerHandle(ServiceInvoker invoker) {
        this.invoker = invoker;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof Command) {
            Asyncs.defaultJobQueue().run(() -> {
                Command command = (Command) msg;
                if (log.isDebugEnabled()) {
                    log.debug("收到消息 id:" + command.id + " func:" + command.func + " data:" + encodeHex(command.bytes));
                }
                invoker.invoke(command);
                if (log.isDebugEnabled()) {
                    log.debug("发送消息 id:" + command.id + " func:" + command.func + " retfunc: " + command.resultFunc +
                            " data:" + encodeHex(command.resultBytes));
                }
                ctx.writeAndFlush(command);
            });
        }
    }

    private static String encodeHex(byte[] bytes) {
        return bytes == null ? "" : Hex.encodeHexString(bytes);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("客户端连接建立" + ctx);

        // 发送所有id
        Command command = invoker.getMethodIds();
        ctx.writeAndFlush(command);
    }


    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("客户端断开连接" + ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("rpc服务端发生异常", cause);
        ctx.close();
    }
}
